
import java.util.logging.Level;
import java.util.logging.Logger;
import processing.core.*;
import java.awt.Point;
import java.util.*;

public class Main extends PApplet {

    PGraphics pg, pg2;
    ArrayList conjuntoFormas;
    ArrayList conjFormasTransformadas;
    Forma rectanguloNav;
    Point puntoAnterior;

    public static void main(String[] args) {
        new CuadroDespliegue().setVisible(true);
    }

    public void setup() {
        size(600, 600);
        background(95, 150, 1);
        pg = createGraphics(600, 300, P3D);
        pg2 = createGraphics(600, 300, P3D);//El que ira cambiando
        image(pg, 0, 0);
        image(pg2, 0, 300);
        conjuntoFormas = new ArrayList<Forma>();
        conjFormasTransformadas = new ArrayList<Forma>();
        crearRectanguloNavegacion();
        crearFormas();
        try {
            conjFormasTransformadas = clonarListaDeFormas(conjuntoFormas);
        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        //trasladarEscena(-100, 0);
        escalarEscena(2);
        dibujarFormas(pg, conjFormasTransformadas);
        dibujarFormas(pg2, conjuntoFormas);
    }

    public ArrayList<Forma> clonarListaDeFormas(ArrayList<Forma> conjFormasInicial) throws Exception {
        ArrayList listaCopia = new ArrayList<Forma>(conjFormasInicial.size());
        //conjFormasTransformadas=ObjectCloner.deepCopy(conjuntoFormas);
        for (Forma formaActual : conjFormasInicial) {
            listaCopia.add(ObjectCloner.deepCopy(formaActual));
        }
        return listaCopia;
    }

    public void crearRectanguloNavegacion() {
        rectanguloNav = new Forma();
        rectanguloNav.vertices.add(new Point(0, 0));
        rectanguloNav.vertices.add(new Point(120, 0));
        rectanguloNav.vertices.add(new Point(120, 60));
        rectanguloNav.vertices.add(new Point(0, 60));
        rectanguloNav.parametroEndShape = CLOSE;
    }

    public void dibujarFormas(PGraphics pgLienzo, ArrayList formasAPintar) {
        pgLienzo.stroke(0);
        Iterator iteradorFormas = formasAPintar.iterator();
        while (iteradorFormas.hasNext()) {
            Forma formaTemp = (Forma) iteradorFormas.next();
            formaTemp.dibujar(pgLienzo, true);
        }

    }

    //Traslada toda la escena
    public void trasladarEscena(int dx, int dy) {
        Iterator iteradorFormas = conjFormasTransformadas.iterator();
        while (iteradorFormas.hasNext()) {
            Forma formaTemp = (Forma) iteradorFormas.next();
            formaTemp.trasladar(dx, dy);
        }
    }

    public void escalarEscena(double factorEscalamiento) {

        Iterator iteradorFormas = conjFormasTransformadas.iterator();
        while (iteradorFormas.hasNext()) {
            Forma formaTemp = (Forma) iteradorFormas.next();
            formaTemp.escalar(factorEscalamiento);
        }
    }

    public void rotarEscena(int anguloRotacion) {

        Iterator iteradorFormas = conjFormasTransformadas.iterator();
        while (iteradorFormas.hasNext()) {
            Forma formaTemp = (Forma) iteradorFormas.next();
            formaTemp.girar(anguloRotacion);
        }
    }

    public void mouseMoved() {

        if(mouseY<300) return;

        if (puntoAnterior == null) {
            puntoAnterior = new Point();
            puntoAnterior.x = mouseX;
            puntoAnterior.y = mouseY;
            trasladarEscena(-1*mouseX, 0);
        }
        Point punto = (Point) rectanguloNav.vertices.get(0);
        int dx, dy;
        dx = mouseX - puntoAnterior.x;
        dy = mouseY - puntoAnterior.y;
        rectanguloNav.trasladar(punto.x * -1, punto.y * -1); //Se traslada el cuadro de nuevo al origen
        rectanguloNav.trasladar(mouseX, mouseY - 300);
        dibujarRectNav();
        pg.background(95, 150, 1); //limpiamos rastro de la escena anterior
        trasladarEscena(-1 * dx, -1 * dy);
        dibujarFormas(pg, conjFormasTransformadas); //Para que no haya "parpadeo" mientras draw es llamada automaticamente
        puntoAnterior.x = mouseX;
        puntoAnterior.y = mouseY;
    }

    public void dibujarRectNav() {
        pg2.background(95, 150, 1); //limpiamos rastro del cuadro de navegación
        dibujarFormas(pg2, conjuntoFormas); //se vuelven a pintar las formas pq se dejó todo en blanco en la línea anterior
        pg2.stroke(255);//color borde del cuadro de navegación
        rectanguloNav.dibujar(pg2, false);
    }

    //En esta función se definen las formas de la escena inicial
    public void crearFormas() {
        Forma rectanguloIglesia = new Forma();

        rectanguloIglesia.vertices.add(new Point(30, 80));
        rectanguloIglesia.vertices.add(new Point(120, 80));
        rectanguloIglesia.vertices.add(new Point(120, 135));
        rectanguloIglesia.vertices.add(new Point(30, 135));
        rectanguloIglesia.parametroEndShape = CLOSE;
        conjuntoFormas.add(rectanguloIglesia);

        Forma techoIglesia = new Forma();
        techoIglesia.parametroBeginShape = TRIANGLES;
        techoIglesia.vertices.add(new Point(30, 80));
        techoIglesia.vertices.add(new Point(40, 20));
        techoIglesia.vertices.add(new Point(50, 80));
        techoIglesia.setColorRelleno(120, 10, 50);
        conjuntoFormas.add(techoIglesia);

        Forma copaArbol = new Forma();
        copaArbol.parametroBeginShape = TRIANGLES;
        copaArbol.setColorRelleno(53, 227, 53);
        copaArbol.vertices.add(new Point(30, 200));
        copaArbol.vertices.add(new Point(40, 135));
        copaArbol.vertices.add(new Point(50, 200));
        copaArbol.vertices.add(new Point(130, 200));
        copaArbol.vertices.add(new Point(140, 135));
        copaArbol.vertices.add(new Point(150, 200));
        conjuntoFormas.add(copaArbol);

        Forma troncoArboles = new Forma();
        troncoArboles.parametroBeginShape = QUADS;
        troncoArboles.setColorRelleno(135, 76, 17);
        troncoArboles.vertices.add(new Point(30, 200));
        troncoArboles.vertices.add(new Point(30, 255));
        troncoArboles.vertices.add(new Point(50, 255));
        troncoArboles.vertices.add(new Point(50, 200));
        troncoArboles.vertices.add(new Point(130, 200));
        troncoArboles.vertices.add(new Point(130, 255));
        troncoArboles.vertices.add(new Point(150, 255));
        troncoArboles.vertices.add(new Point(150, 200));
        conjuntoFormas.add(troncoArboles);


        Forma prueba = new Forma();
        prueba.vertices.add(new Point(230, 80));
        prueba.vertices.add(new Point(220, 80));
        prueba.vertices.add(new Point(220, 135));
        prueba.vertices.add(new Point(230, 135));
        prueba.parametroEndShape = CLOSE;
        conjuntoFormas.add(prueba);

    }

    public void keyPressed() {
        if (key == 'r') {
            rectanguloNav.girar(10);
            rotarEscena(10);
        } else if (key == 'e') {
            rectanguloNav.girar(-10);
            rotarEscena(-10);
        }

        if (key == 'z') {
            escalarEscena(1.1);
            rectanguloNav.escalar(0.9);
        } else if (key == 'x') {
            escalarEscena(0.9);
            rectanguloNav.escalar(1.1);
        }

    }

    public void draw() {
        image(pg, 0, 0);
        image(pg2, 0, 300);
        pg.background(95, 150, 1); //limpiamos rastro de la escena anterior
        pg2.background(95, 150, 1); //limpiamos rastro de la escena anterior
        dibujarRectNav();
        dibujarFormas(pg, conjFormasTransformadas);
        dibujarFormas(pg2, conjuntoFormas);


//

//
////cuerpo del perro
//        pg.beginDraw();
//        pg.beginShape();
//        pg.fill(225, 166, 38);
//        pg.vertex(425, 140);
//        pg.vertex(285, 140);
//        pg.vertex(285, 200);
//        pg.vertex(425, 200);
//        pg.endShape(CLOSE);
//        pg.endDraw();
//
////cabeza del perro
//        pg.beginDraw();
//        pg.beginShape();
//        pg.fill(225, 166, 38);
//        pg.vertex(305, 115);
//        pg.vertex(265, 115);
//        pg.vertex(265, 165);
//        pg.vertex(305, 165);
//        pg.endShape(CLOSE);
//        pg.endDraw();
//
////ojos del perro
//        pg.beginDraw();
//        pg.beginShape();
//        pg.fill(0);
//        pg.vertex(282, 125);
//        pg.vertex(277, 125);
//        pg.vertex(277, 130);
//        pg.vertex(282, 130);
//        pg.endShape(CLOSE);
//        pg.endDraw();
//
//        pg.beginDraw();
//        pg.beginShape();
//        pg.fill(0);
//        pg.vertex(293, 125);
//        pg.vertex(288, 125);
//        pg.vertex(288, 130);
//        pg.vertex(293, 130);
//        pg.endShape(CLOSE);
//        pg.endDraw();
////lengua del perro
//
//        pg.beginDraw();
//        pg.beginShape();
//        pg.fill(236, 19, 40);
//        pg.vertex(297, 150);
//        pg.vertex(273, 150);
//        pg.vertex(273, 155);
//        pg.vertex(297, 155);
//        pg.endShape(CLOSE);
//        pg.endDraw();
//        //piernas delanteras
//        pg.beginDraw();
//        pg.beginShape();
//        pg.fill(225, 166, 38);
//        pg.vertex(300, 200);
//        pg.vertex(300, 255);
//        pg.vertex(310, 255);
//        pg.vertex(310, 200);
//        pg.vertex(320, 200);
//        pg.vertex(320, 255);
//        pg.vertex(330, 255);
//        pg.vertex(330, 200);
//        pg.endShape(CLOSE);
//        pg.endDraw();
//
//        //piernas traseras
//        pg.beginDraw();
//        pg.beginShape();
//        pg.fill(225, 166, 38);
//        pg.vertex(380, 200);
//        pg.vertex(380, 255);
//        pg.vertex(390, 255);
//        pg.vertex(390, 200);
//        pg.vertex(400, 200);
//        pg.vertex(400, 255);
//        pg.vertex(410, 255);
//        pg.vertex(410, 200);
//        pg.endShape(CLOSE);
//        pg.endDraw();


    }
}
